package GUI;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Toolkit;
import java.util.Observable;
import java.util.Observer;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingConstants;
import javax.swing.border.BevelBorder;

import lejos.pc.comm.NXTInfo;
import BE.NXTDataEvent;
import Controllers.ConnectionFrameListener;
import Controllers.Controller;

/**
 * Shows a frame containing a view for drawing a map according to received nxt
 * data.
 * @author Danny, Didzis, Liviu
 *
 */
public class ConnectionFrame extends JFrame implements Observer {

	private static final long serialVersionUID = 6226590982536283014L;
	private JScrollPane mapContainer;
	private MapPanel mapPanel;
	private JPanel buttonsPanel;
	private JPanel statusbarPannel;
	private JLabel statusLabel;
	private JButton startMappingButton;
//	private JCheckBox chkShowGrid;
	private NXTInfo nxtDevice;

	// private Controller controller;

	public ConnectionFrame(NXTInfo deviceInfo, double X, double Y,
			Controller control) {

		nxtDevice = deviceInfo;

		setTitle(nxtDevice.name);

		// size of the screen
		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();

		// height of the task bar
		Insets scnMax = Toolkit.getDefaultToolkit().getScreenInsets(
				getGraphicsConfiguration());
		int taskBarSize = scnMax.bottom;

		Dimension frame = new Dimension((int) (screenSize.getWidth() - X - 3),
				(int) (screenSize.getHeight() - taskBarSize - 3));

		Dimension frameMinimum = new Dimension(
				(int) (screenSize.getWidth() * 0.35),
				(int) (screenSize.getHeight() * 0.20));

		setSize(frame);
		setMinimumSize(frameMinimum);
		setLocation((int) X, (int) Y);
		setVisible(true);

		SetupComponents();

		control.ConnectionFrameCreated(this);
	}

	/**
	 * Layout components on the frame.
	 */
	private void SetupComponents() {

		setLayout(new GridBagLayout());

		JPanel MainPanel = new JPanel(new GridBagLayout());
		MainPanel.setBorder(BorderFactory.createEtchedBorder(Color.lightGray,
				Color.lightGray.darker()));
		GridBagConstraints c = new GridBagConstraints();
		c.gridx = 0;
		c.gridy = 0;
		c.gridwidth = 1;
		c.gridheight = 1;
		c.weightx = 1;
		c.weighty = 1;
		c.fill = GridBagConstraints.BOTH;
		add(MainPanel, c);

		buttonsPanel = new JPanel(new GridBagLayout());
		buttonsPanel.setBorder(BorderFactory.createEtchedBorder(
				Color.lightGray, Color.lightGray.darker()));
		c = new GridBagConstraints();
		c.gridx = 0;
		c.gridy = 0;
		c.gridwidth = 1;
		c.gridheight = 1;
		c.weightx = 0;
		c.weighty = 0;
		c.insets = new Insets(1, 1, 1, 1);
		c.fill = GridBagConstraints.HORIZONTAL;
		c.anchor = GridBagConstraints.PAGE_START;
		MainPanel.add(buttonsPanel, c);

		// mapContainer = new JPanel(new ScrollPaneLayout());
		mapPanel = new MapPanel(this);

		// mapPanel.setPreferredSize(new Dimension(500, 500));
		mapContainer = new JScrollPane(mapPanel);
		mapContainer.setBorder(BorderFactory.createEtchedBorder(
				Color.lightGray, Color.lightGray.darker()));

		c.gridx = 0;
		c.gridy = 1;
		c.gridwidth = 1;
		c.gridheight = 1;
		c.weightx = 1;
		c.weighty = 1;
		c.insets = new Insets(1, 1, 1, 1);
		c.fill = GridBagConstraints.BOTH;
		MainPanel.add(mapContainer, c);

		statusbarPannel = new JPanel();
		statusbarPannel.setBorder(new BevelBorder(BevelBorder.LOWERED));
		statusbarPannel.setLayout(new BoxLayout(statusbarPannel,
				BoxLayout.X_AXIS));
		c = new GridBagConstraints();
		c.gridx = 0;
		c.gridy = 2;
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.gridheight = 1;
		c.weightx = 0;
		c.weighty = 0;
		c.fill = GridBagConstraints.HORIZONTAL;
		c.anchor = GridBagConstraints.PAGE_END;
		MainPanel.add(statusbarPannel, c);

		statusLabel = new JLabel();
		statusLabel.setHorizontalAlignment(SwingConstants.LEFT);
		statusLabel.setText("Ready...");
		statusbarPannel.add(statusLabel);

		startMappingButton = new JButton("Start");
		c = new GridBagConstraints();
		c.gridx = 0;
		c.gridy = 0;
		c.gridwidth = 1;
		c.gridheight = 1;
		c.weightx = 1;
		c.weighty = 1;
		c.insets = new Insets(1, 1, 1, 1);
		c.anchor = GridBagConstraints.FIRST_LINE_START;
		buttonsPanel.add(startMappingButton, c);
		
//		chkShowGrid = new JCheckBox("Show Grid");
//		chkShowGrid.setSelected(true);
//		c = new GridBagConstraints();
//		c.gridx = 1;
//		c.gridy = 0;
//		c.gridwidth = 1;
//		c.gridheight = 1;
//		c.weightx = 1;
//		c.weighty = 1;
//		c.insets = new Insets(1, 1, 1, 1);
//		c.anchor = GridBagConstraints.LINE_START;
//		buttonsPanel.add(chkShowGrid, c);
//		
	}

	/**
	 * Method called when a notifyObservers is invoked
	 * from the observable object monitored.
	 */
	@Override
	public void update(Observable source, Object data) {
		if (data instanceof NXTDataEvent) {
			NXTDataEvent event = (NXTDataEvent) data;
			mapPanel.drawData(event.getData());
		}
	}

	/**
	 * Register a mouse listener to the view for enabling
	 * scrolling through the map with mouse clicks.
	 * @param listener - MouseListener interface.
	 */
	public void addMapPanelMouseListener(ConnectionFrameListener listener) {
		mapPanel.addMouseListener(listener);
		mapPanel.addMouseMotionListener(listener);
	}

	/**
	 * Identifies the center of a panel.
	 * @return a clone of the center point of the panel.
	 */
	public Point copyCenter() {
		return mapPanel.getCenterClone();
	}

	/**
	 * Updates the center point of a panel.
	 * @param p - the panel to update on.
	 */
	public void updateCenter(Point p) {
		mapPanel.updateCenter(p);

	}

}
